home *** CD-ROM | disk | FTP | other *** search
- /* Mail Command Line Interface -- Clients
- * Copyright 1992 William Allen Simpson
- * partly based on a MAIL client design by Anders Klemets, SM0RGV
- *
- * Mods by PA0GRI
- * Improved param cracking
- */
- #include <ctype.h>
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
- #include "global.h"
- #include "timer.h"
- #include "proc.h"
- #include "socket.h"
- #include "domain.h"
- #include "cmdparse.h"
- #include "files.h"
- #include "netuser.h"
- #include "mailcli.h"
- #include "mailutil.h"
- #include "smtp.h"
-
-
- /* Tracing levels:
- 0 - no tracing
- 1 - serious errors reported
- 2 - transient errors reported
- 3 - session progress reported
- */
- unsigned short Mailtrace = 1;
-
- int Mailquiet = FALSE;
-
- struct mailservers *Mailservers = NULLMAIL;
-
- static int domsquiet __ARGS((int argc,char *argv[],void *p));
- static int domstrace __ARGS((int argc,char *argv[],void *p));
- static int doadds __ARGS((int argc,char *argv[],void *p));
- static int dodrops __ARGS((int argc,char *argv[],void *p));
- static int dokicks __ARGS((int argc,char *argv[],void *p));
- static int dolists __ARGS((int argc,char *argv[],void *p));
-
- static void mailtick __ARGS((void *tp));
-
- static char mreaderr[] = "popmail: Missing";
-
- static struct cmds Mailcmds[] = {
- "addserver", doadds, 0, 2, "popmail addserver <mailserver> [<seconds>] [hh:mm-hh:mm] <protocol> <mailbox> <username> <password>",
- "dropserver", dodrops, 0, 2, "popmail dropserver <mailserver>",
- "kick", dokicks, 0, 2, "popmail kick <mailserver>",
- "list", dolists, 0, 0, NULLCHAR,
- "quiet", domsquiet, 0, 0, NULLCHAR,
- "trace", domstrace, 0, 0, NULLCHAR,
- NULLCHAR,
- };
-
-
- int
- domsread(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return subcmd(Mailcmds,argc,argv,p);
- }
-
-
- static int
- domsquiet(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- return setbool(&Mailquiet,"mail quiet",argc,argv);
- }
-
-
- static int
- domstrace(argc, argv, p)
- int argc;
- char *argv[];
- void *p;
- {
- return setshort(&Mailtrace,"mail tracing",argc,argv);
- }
-
-
-
- static int
- doadds(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mailservers *np;
- char *fullname;
- int i;
- int32 addr;
-
- fullname = domainsuffix(argv[1]);
- if((addr = resolve(fullname)) == 0L){
- tprintf("Unknown host %s\n",fullname);
- /* domainsuffix() ALLOCATED memory !, so free it - WG7J */
- free(fullname);
- return 1;
- }
-
- i = 2;
- np = (struct mailservers *) callocw(1,sizeof(struct mailservers));
- np->hostname = fullname;
- np->next = Mailservers;
- Mailservers = np;
- np->lowtime = np->hightime = -1;
- np->timer.func = mailtick; /* what to call on timeout */
- np->timer.arg = (void *)np;
-
- if( argc > i && isdigit(*argv[i])){
- if(strchr(argv[i],'-') == NULLCHAR )
- /* set timer duration */
- set_timer(&np->timer,atol(argv[i++])*1000L);
- }
-
- if( argc > i && isdigit(*argv[i])){
- int lh, ll, hh, hl;
- sscanf(argv[i++], "%d:%d-%d:%d", &lh, &ll, &hh, &hl);
- np->lowtime = lh * 100 + ll;
- np->hightime = hh * 100 + hl;
- }
-
- if ( argc > i ) {
- struct daemon *dp = Mailreaders;
-
- for ( ; dp->name != NULLCHAR ; dp++ ) {
- if ( stricmp(dp->name, argv[i]) == 0 ) {
- np->reader = dp;
- break;
- }
- }
- if ( np->reader == NULLDAEMON ) {
- tprintf("unrecognized protocol '%s'\n", argv[i] );
- goto quit;
- }
- i++;
- } else {
- tprintf("%s protocol\n",mreaderr);
- goto quit;
- }
-
- if ( argc > i ) {
- np->mailbox = strdup(argv[i++]);
- } else {
- tprintf("%s mailbox\n",mreaderr);
- goto quit;
- }
-
- if ( argc > i ) {
- np->username = strdup(argv[i++]);
- } else {
- tprintf("%s username\n",mreaderr);
- goto quit;
- }
-
- if ( argc > i ) {
- np->password = strdup(argv[i++]);
- } else {
- tprintf("%s password\n",mreaderr);
- goto quit;
- }
-
- start_timer(&np->timer); /* and fire it up */
- return 0;
-
- quit:
- Mailservers = np->next;
- free(np->hostname);
- free(np->username);
- free(np->password);
- free(np->mailbox);
- free((char *)np);
- return -1;
- }
-
-
- static int
- dodrops(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mailservers *np, *npprev = NULLMAIL;
- char *fullname;
-
- fullname = domainsuffix(argv[1]);
- for (np = Mailservers; np != NULLMAIL; npprev = np, np = np->next) {
- if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
- stop_timer(&np->timer);
- free(np->hostname);
- free(np->username);
- free(np->password);
- free(np->mailbox);
-
- if(npprev != NULLMAIL)
- npprev->next = np->next;
- else
- Mailservers = np->next;
- free((char *)np);
- return 0;
- }
- }
- tprintf("No such server enabled.\n");
- return -1;
- }
-
-
- static int
- dolists(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mailservers *np;
-
- for (np = Mailservers; np != NULLMAIL; np = np->next) {
- char tbuf[80];
- if (np->lowtime != -1 && np->hightime != -1)
- sprintf(tbuf, " %02d:%02d-%02d:%02d",
- np->lowtime/100,
- np->lowtime%100,
- np->hightime/100,
- np->hightime%100);
- else
- tbuf[0] = '\0';
- tprintf("%-32s (%lu/%lu%s) %s %s\n",
- np->hostname,
- read_timer(&np->timer) /1000L,
- dur_timer(&np->timer) /1000L,
- tbuf,
- np->reader->name,
- np->username );
- }
- return 0;
- }
-
-
- static int
- dokicks(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct mailservers *np;
- char *fullname;
-
- fullname = domainsuffix(argv[1]);
- for (np = Mailservers; np != NULLMAIL; np = np->next) {
- if(strnicmp(np->hostname,fullname,strlen(fullname)) == 0) {
- if(availmem() - np->reader->stksize < Memthresh){
- tprintf("insufficient memory\n");
- return 1;
- }
- /* If the timer is not running, the timeout function
- * has already been called, and we don't want to call
- * it again.
- */
- if ( np->timer.duration == 0
- || run_timer(&np->timer) ) {
- stop_timer(&np->timer);
- newproc( np->reader->name,
- np->reader->stksize,
- np->reader->fp,
- 0, np, NULL,0);
- }
- return 0;
- }
- }
- tprintf("No such server enabled.\n");
- return -1;
- }
-
-
- static void
- mailtick(tp)
- void *tp;
- {
- struct mailservers *np = tp;
- struct tm *ltm;
- time_t t;
- int now;
-
- if(availmem() - np->reader->stksize < Memthresh){
- /* Memory is tight, don't do anything */
- if (Mailtrace >= 2)
- log(-1,"%s tick exit -- low memory",
- np->reader->name);
- start_timer(&np->timer);
- return;
- }
-
- time(&t);
- ltm = localtime(&t);
- now = ltm->tm_hour * 100 + ltm->tm_min;
- if (np->lowtime < np->hightime) { /* doesn't cross midnight */
- if (now < np->lowtime || now >= np->hightime) {
- if (Mailtrace >= 2)
- log(-1,"%s window to '%s' not open",
- np->reader->name,
- np->hostname);
- start_timer(&np->timer);
- return;
- }
- } else {
- if (now < np->lowtime && now >= np->hightime) {
- if (Mailtrace >= 2)
- log(-1,"%s window to '%s' not open",
- np->reader->name,
- np->hostname);
- start_timer(&np->timer);
- return;
- }
- }
-
- newproc( np->reader->name, np->reader->stksize, np->reader->fp,
- 0, tp, NULL,0);
- }
-
-
- int
- mailresponse(s,buf,comment)
- int s; /* Socket index */
- char *buf; /* User buffer */
- char *comment; /* comment for error message */
- {
- if (recvline(s,buf,RLINELEN) != -1) {
- if ( Mailtrace >= 3 ) {
- rip(buf);
- log(s,"%s <== %s", comment, buf);
- }
- return 0;
- }
- if ( Mailtrace >= 2 )
- log(s,"receive error for %s response", comment);
- return -1;
- }
-
-
- /* Check to see if mailbox is already busy (or perpetually locked) */
- int
- mailbusy( np )
- struct mailservers *np;
- {
- int countdown = 10;
-
- while ( mlock( Mailspool, np->mailbox ) ) {
- if ( --countdown > 0 ) {
- mspause( 60000L ); /* 60 seconds */
- } else {
- start_timer(&np->timer);
- return TRUE;
- }
- }
-
- /* release while processing */
- rmlock( Mailspool, np->mailbox );
- return FALSE;
- }
-
-
-